//
//  FileUtiles.cpp
//  MyClient
//
//  Created by RJ G on 2025/5/3.
//
#include "FileUtiles.h"

const int BUFFER_SIZE = 1024;
const int ARTICAL_LENGTH = 17;
const int CONTINUE = 25;
extern int g_server;
std::map<std::string, std::map<std::string, std::pair<int, std::string>>> data;
std::map<std::string, std::pair<std::string, std::string>> autoLearn;
std::vector<std::string> chars;

void readUTF8Chars(const std::string &str) {
    std::cout << "解析中：";
    int i = 0;
    int count = 0;
    while (i < str.length()) {
        unsigned char c = str[i];
        int charLen = 1;
        if ((c & 0x80) == 0x00) {         // 1字节（英文）
            charLen = 1;
        } else if ((c & 0xE0) == 0xC0) {  // 2字节
            charLen = 2;
        } else if ((c & 0xF0) == 0xE0) {  // 3字节
            charLen = 3;
        } else if ((c & 0xF8) == 0xF0) {  // 4字节
            charLen = 4;
        }
        chars.push_back(str.substr(i, charLen));
        i += charLen;
        if (++count % 10000 == 0) {
            usleep(100 * 1000);
            std::cout << '-';
        }
    }
    std::cout << std::endl << "解析完成" << std::endl;
}

void readUTF8File(const std::string &filename) {
    std::ifstream file(filename, std::ios::binary);
    if (!file) {
        std::cerr << "文件打开失败" << std::endl;
        return;
    }
    std::string content((std::istreambuf_iterator<char>(file)),
                       std::istreambuf_iterator<char>());
    readUTF8Chars(content);
    if (chars.size() < CONTINUE) {
        return;
    }
    for (int i = 0; i < chars.size() - CONTINUE; i++) {
        if (chars[i] == " " || chars[i + 1] == " " || chars[i] == "\n" || chars[i + 1] == "\n") {
            continue;
        }
        std::string temp;
        for (int j = 0; j < CONTINUE; j++) {
            if (chars[i + j + 1] == "\n" || chars[i + j + 1] == " ") {
                continue;
            }
            temp += chars[i + j + 1];
        }
        data[chars[i]][temp].first++;
        data[chars[i]][temp].second = chars[i + CONTINUE];
    }
    for (std::pair<std::string, std::map<std::string, std::pair<int, std::string>>> element : data) {
        int max = INT_MIN;
        for (std::pair<std::string, std::pair<int, std::string>> strs : element.second) {
            if (strs.second.first > max) {
                max = strs.second.first;
                autoLearn[element.first].first = strs.first;
                autoLearn[element.first].second = strs.second.second;
            }
        }
    }
    chars.clear();
}

void receiveFile()
{
    std::string fileName = "received.txt";
    FILE* fp = std::fopen(fileName.c_str(), "wb");
    char buffer[BUFFER_SIZE] = {0};
    std::cout << "文件接收中：";
    long len = BUFFER_SIZE;
    int count = 0;
    while (len == BUFFER_SIZE) {
        len = read(g_server, buffer, BUFFER_SIZE);
        fwrite(buffer, sizeof(char), len, fp);
        if (!(count++ % 10)) {
            std::cout << '-';
        }
        usleep(10 * 1000);
    }
    fclose(fp);
    std::cout << std::endl << "文件接收完成" << std::endl;
}

void generateArtical(std::string &question)
{
    readUTF8Chars(question);
    int count = 0;
    std::string current = chars[chars.size() - 1];
    std::set<std::string> mark;
    bool flag = false;
    bool start = false;
    srand((unsigned int)time(NULL));
    while (count++ < ARTICAL_LENGTH || flag) {
        mark.insert(current);
        if (count > ARTICAL_LENGTH * 2 || (flag && autoLearn[current].first.find("。") != std::string::npos)) {
            std::cout << autoLearn[current].first.substr(0, autoLearn[current].first.find("。") + sizeof("。") - 1);
            break;
        }
        if (!start) {
            if (autoLearn[current].first.find("。") != std::string::npos) {
                std::cout << autoLearn[current].first.substr(autoLearn[current].first.find("。") + sizeof("。") - 1);
                start = true;
            }
        } else {
            std::cout << autoLearn[current].first;
        }
        current = autoLearn[current].second;
        int temp = 0;
        while (temp++ < 10 && (autoLearn.find(current) == autoLearn.end() || mark.find(current) != mark.end())) {
            current = chars[(double)rand() / RAND_MAX * chars.size()];
        }
        usleep(100 * 1000);
        if (count == ARTICAL_LENGTH) {
            flag = true;
        }
    }
    std::cout << std::endl;
    chars.clear();
}
